package cn.com.dashihui.wx.controller;

import org.apache.log4j.Logger;

import com.jfinal.aop.Clear;
import com.jfinal.kit.HttpKit;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.weixin.sdk.api.ApiConfigKit;
import com.jfinal.weixin.sdk.api.ApiResult;
import com.jfinal.weixin.sdk.api.SnsAccessToken;
import com.jfinal.weixin.sdk.api.SnsAccessTokenApi;
import com.jfinal.weixin.sdk.api.SnsApi;

import cn.com.dashihui.wx.common.Constants;
import cn.com.dashihui.wx.dao.Community;
import cn.com.dashihui.wx.dao.Store;
import cn.com.dashihui.wx.dao.User;
import cn.com.dashihui.wx.dao.WxUser;
import cn.com.dashihui.wx.interceptor.AuthLocationInterceptor;
import cn.com.dashihui.wx.interceptor.AuthLoginInterceptor;
import cn.com.dashihui.wx.kit.CommonKit;
import cn.com.dashihui.wx.kit.InviteCodeKit;
import cn.com.dashihui.wx.kit.MapKit;
import cn.com.dashihui.wx.kit.SMSKit;
import cn.com.dashihui.wx.kit.ValidateKit;
import cn.com.dashihui.wx.service.CommunityService;
import cn.com.dashihui.wx.service.GoodsService;
import cn.com.dashihui.wx.service.StoreService;
import cn.com.dashihui.wx.service.UserService;
import net.sf.json.JSONObject;

public class SystemController extends BaseController{
	private Logger logger = Logger.getLogger(getClass());
	private CommunityService communityService = new CommunityService();
	private StoreService storeService = new StoreService();
	private GoodsService goodsService = new GoodsService();
	private UserService userService = new UserService();
	
	/**
	 * 跳转至定位页面
	 */
	@Clear(AuthLocationInterceptor.class)
	public void location(){
		//获取在页面上调用微信jsapi所需要的参数
		getJSApiParams(PropKit.get("constants.url_prev")+"/location");
		//百度定位所需要的key
		setAttr("baidukey", PropKit.get("baidu.key"));
		render("location.jsp");
	}

	/**
	 * 请求百度云检索接口
	 */
	public void lbs(){
		String location = getPara("location");
		if(!StrKit.isBlank(location)&&location.indexOf(",")>0&&location.indexOf(".")>0){
			String api = "http://api.map.baidu.com/geosearch/v3/nearby?ak="+PropKit.get("baidu.key")+"&geotable_id="+PropKit.get("baidu.geotable_id")
					+"&location="+location+"&radius="+PropKit.get("baidu.radius")
					//按距离由小到大排序
					+"&sortby=distance:1";
			String resultStr = HttpKit.get(api);
			renderSuccess(MapKit.one().put("lbs", JSONObject.fromObject(resultStr)).getAttrs());
			return;
		}
		renderFailed();
	}
	
	/**
	 * 确定定位
	 * @param baidukey 用户所选择的位置的百度KEY
	 */
	public void locate(){
		String baidukey = getPara("baidukey");
		if(!StrKit.isBlank(baidukey)){
			Community community = communityService.findByBaidukey(baidukey);
			
			if(community!=null){
				Store store = storeService.findById(community.getInt("storeid"));
				if(store!=null){
					//将店铺id保存到用户表中
					User user = getCurrentUser();
					if(user != null) {
						user.set("storeid", community.getInt("storeid")).update();
					}
					//判断是定位页面跳过来的时候，将关联的店铺信息放入session，然后重新跳转首页，避免用户看到参数BAIDUKEY
					setSessionAttr(Constants.STORE, store);
					renderSuccess();
					return;
				}
			}
		}
		renderFailed();
	}
	
	/**
	 * 跳转首页
	 */
	public void index(){
		//1.店铺轮播图
		setAttr("adList",storeService.findAd(getCurrentStoreid()));
		//2.查询各标签及N条商品数量
		setAttr("tagList",goodsService.getAllTag(getCurrentStoreid(),9));
		//3.查询最新一条店铺通知
		setAttr("tip", storeService.findLastTip(getCurrentStoreid()));
		render("index.jsp");
	}
	
	/**
	 * 微信OAuth2网页授权回调处理
	 */
	@Clear
	public void oauth(){
		String code = getPara("code");
		String validcode = getPara("state");
		String backurl = getPara("backurl");
		String session_validcode = getSessionAttr(Constants.WX_OAUTH_VALIDCODE);
		logger.error("code:"+code+",state:"+validcode+",backurl:"+backurl+",session_validate:"+session_validcode);
		if(StrKit.isBlank(validcode)||StrKit.isBlank(session_validcode)||!validcode.equals(session_validcode)){
			logger.error("参数错误！");
			removeSessionAttr(Constants.WX_OAUTH);
			redirect("/index");
			return;
		}
		//移除验证码
		removeSessionAttr(Constants.WX_OAUTH_VALIDCODE);
		if(StrKit.isBlank(code)){
			//用户未同意授权，此时可不理会，依然跳转首页
			logger.error("用户未同意授权，此时可不理会，依然跳转首页");
		}else{
			logger.error("用户同意授权，获取access_token");
			//请求接口，获取access_token
			SnsAccessToken result = SnsAccessTokenApi.getSnsAccessToken(ApiConfigKit.getApiConfig().getAppId(),ApiConfigKit.getApiConfig().getAppSecret(),code);
			if(result.getErrorCode()!=null){
				//获取access_token失败，此时可不理会，依然跳转首页
				logger.error("获取access_token异常："+result.getErrorCode()+"，"+result.getErrorMsg());
			}else{
				logger.error("成功获取access_token，准备获取用户信息");
				//成功，获取用户信息
				ApiResult userinfo = SnsApi.getUserInfo(result.getAccessToken(), result.getOpenid());
				logger.error("获取用户信息："+userinfo.getJson());
				if(userinfo.isSucceed()){
					logger.error("获取用户信息成功！");
					String openid = userinfo.getStr("openid");
					//判断用户信息是否已经存在
					WxUser wxUser = WxUser.me().findFirst("SELECT * FROM t_bus_user_wx WHERE openid=?",openid);
					if(wxUser!=null){
						logger.error("微信用户已经存在，更新！");
						//更新
						Db.update("UPDATE t_bus_user_wx SET nickname=?,sex=?,province=?,city=?,country=?,headimgurl=?,unionid=?,access_token=?,refresh_token=? WHERE openid=?",
								userinfo.getStr("nickname"),
								userinfo.getInt("sex"),
								userinfo.getStr("province"),
								userinfo.getStr("city"),
								userinfo.getStr("country"),
								userinfo.getStr("headimgurl"),
								userinfo.getStr("unionid"),
								result.getAccessToken(),
								result.getRefresh_token(),
								userinfo.getStr("openid"));
					}else{
						logger.error("微信用户不存在，添加！");
						//添加
						Db.update("INSERT INTO t_bus_user_wx(openid,nickname,sex,province,city,country,headimgurl,unionid,access_token,refresh_token) VALUES(?,?,?,?,?,?,?,?,?,?)",
								userinfo.getStr("openid"),
								userinfo.getStr("nickname"),
								userinfo.getInt("sex"),
								userinfo.getStr("province"),
								userinfo.getStr("city"),
								userinfo.getStr("country"),
								userinfo.getStr("headimgurl"),
								userinfo.getStr("unionid"),
								result.getAccessToken(),
								result.getRefresh_token());
					}
					//获取对应的用户信息
					User user = User.me().findFirst("SELECT A.*,B.openid FROM t_bus_user A INNER JOIN t_bus_user_wx B ON A.wxUserid=B.id AND B.openid=?",openid);
					if(user!=null){
						logger.error("关联用户存在：\n"+user);
						setSessionAttr(Constants.USER, user);
						
						//将店铺信息放到session中
						int storeid = user.getInt("storeid");
						Store store = storeService.findById(storeid);
						if(store!=null){
							setSessionAttr(Constants.STORE, store);
						}
					}else{
						logger.error("关联用户不存在！");
					}
					//再获取最新的微信信息保存，以便用户进行注册或登录时，记录关联关系
					setSessionAttr(Constants.WX_USER, WxUser.me().findFirst("SELECT * FROM t_bus_user_wx WHERE openid=?",openid));
				}else{
					logger.error("获取用户信息失败！");
				}
			}
		}
		//记录变量，表示已经进行过用户授权，不需要再进行第二次
		setSessionAttr(Constants.WX_OAUTH, true);
		if(StrKit.isBlank(backurl)){
			logger.error("重定向至首页");
			//重定向至首页
			redirect("/index");
		}else{
			logger.error("重定向至"+backurl);
			redirect(backurl);
		}
	}
	
	/**
     * 注册时，生成并发送N位短信验证码
	 * @param PHONE 手机号码
     * @return CONTENT 生成并发送的N位短信验证码
     */
    public void sendRegCode(){
    	String msisdn = getPara("phone");
    	if(StrKit.isBlank(msisdn)){
    		renderResult(1,"参数PHONE不能为空");
    		return;
    	}else if(userService.findByUsername(msisdn)!=null){
    		renderResult(2,"手机号已经存在，请直接登录");
    		return;
    	}
    	//判断session中是否已经存在未过期的验证码
    	String randomNum = getSessionAttr("REGIST_VALID_CODE");
		if(randomNum==null){
			//否则生成新的验证码
			randomNum = CommonKit.randomNum();
		}
		if(SMSKit.sendRegCode(msisdn, randomNum)){
			setSessionAttr("REGIST_VALID_CODE", randomNum);
			if(PropKit.getBoolean("debug.sms")){
				//短信接口调试模式时，将短信验证码返回给客户端
				renderSuccess(randomNum);
				return;
			}else{
				renderSuccess();
				return;
			}
		}
		renderFailed("验证码发送失败，请重新获取");
    }
	
	/**
	 * 会员分享后，用户点击链接所查看的页面<br/>
	 * 任何人可看，也不需要验证微信信息是否获取
	 */
	public void invite(){
		String inviteCode = getPara(0);
		if(StrKit.isBlank(inviteCode)){
			redirect("/index");
			return;
		}
		//将邀请码反向转换为用户ID，并验证对应的用户是否存在
		User user = userService.findByUserInviteCode(inviteCode);
		if(user==null){
			redirect("/index");
			return;
		}
		//验证通过后，显示邀请页面
		setAttr("inviteCode", inviteCode);
		render("invite.jsp");
	}
	
	/**
	 * 跳转至注册页面
	 */
	public void regist(){
		String inviteCode = getPara(0);
		if(!StrKit.isBlank(inviteCode)&&userService.findByUserid(Long.valueOf(InviteCodeKit.codeToId(inviteCode)).intValue())!=null){
			setAttr("inviteCode", inviteCode);
    	}
		render("regist.jsp");
	}
	
	/**
	 * 用户注册
	 * @param PHONE 手机号码
	 * @param PASSWORD 密码
	 * @param PASSWORDCONFIRM 确认密码
	 * @param CODE 短信验证码
	 * @param COMMUNITYID 定位后获取的社区ID
	 * @return 1：手机号不能为空，2：手机号格式不正确，3：手机号已经存在，不能重复注册，4：密码不能为空，5：密码只能填写数字、字母、下划线组合，
	 * 			6：请保持密码长度在6-18之间，7：确认密码不能为空，8：两次密码输入不一致，9：验证码，10：未获取短信验证码，请重新获取，11：验证码不正确，12：邀请码不正确
	 */
    public void doRegist(){
    	String msisdn = getPara("phone");
    	String password = getPara("password");
    	String passwordConfirm = getPara("passwordConfirm");
    	String code = getPara("code");
    	String inviteCode = getPara("icode");
    	//验证各参数
    	if(StrKit.isBlank(msisdn)){
    		renderResult(1,"手机号不能为空");
    		return;
    	}else if(!ValidateKit.Mobile(msisdn)){
    		renderResult(2,"手机号格式不正确");
    		return;
    	}else if(userService.findByUsername(msisdn)!=null){
    		renderResult(3,"手机号已经存在，不能重复注册");
    		return;
    	}else if(StrKit.isBlank(password)){
    		renderResult(4,"密码不能为空");
    		return;
    	}else if(ValidateKit.Password_reg(password)){
    		renderResult(5,"密码只能填写数字、字母、下划线组合");
    		return;
    	}else if(password.length()<6||password.length()>18){
    		renderResult(6,"请保持密码长度在6-18之间");
    		return;
    	}else if(StrKit.isBlank(passwordConfirm)){
    		renderResult(7,"确认密码不能为空");
    		return;
    	}else if(!password.equals(passwordConfirm)){
    		renderResult(8,"两次密码输入不一致");
    		return;
    	}else if(StrKit.isBlank(code)){
    		renderResult(9,"验证码不能为空");
    		return;
    	}else if(!StrKit.isBlank(inviteCode)&&userService.findByUserid(Long.valueOf(InviteCodeKit.codeToId(inviteCode)).intValue())==null){
    		renderResult(12,"邀请码不正确");
    		return;
    	}
    	//验证短信验证码
    	String codeInSession = getSessionAttr("REGIST_VALID_CODE");
    	if(StrKit.isBlank(codeInSession)){
    		renderResult(10,"未获取短信验证码，请重新获取");
    		return;
    	}else if(!codeInSession.equals(code)){
    		renderResult(11,"验证码不正确");
    		return;
    	}
		//移除缓存中的验证码
    	removeSessionAttr("REGIST_VALID_CODE");
    	//新建
    	User user = new User()
    			.set("username", msisdn)
    			.set("password", CommonKit.encryptPassword(password))
    			.set("nickName", CommonKit.hideMsisdn(msisdn))
    			.set("communityid", 0)
    			.set("inviteUserid", Long.valueOf(InviteCodeKit.codeToId(inviteCode)).intValue());
    	//判断当前微信用户是否授权，如果已经授权，并且同意绑定当前微信号注册，则将注册信息与记录的微信用户信息关联，并设置默认的信息（性别、头像）
		WxUser wxUser = getCurrentWxUser();
		if(wxUser!=null){
			user.set("wxUserid", wxUser.get("id"));
			user.set("sex", wxUser.get("sex"));
			user.set("avator", wxUser.get("headimgurl"));
			user.set("nickName", wxUser.get("nickname"));
		}
    	//保存用户信息
    	if(userService.save(user)){
			renderSuccess();
			return;
    	}
    	renderFailed("注册失败");
    }
	
	/**
	 * 跳转至登录页面
	 */
	public void login(){
		render("login.jsp");
	}
    
    /**
	 * 用户登录
	 * @param PHONE 手机号码
	 * @param PASSWORD 密码
	 */
    public void doLogin(){
    	String msisdn = getPara("phone");
    	String password = getPara("password");
    	//验证各参数
    	if(StrKit.isBlank(msisdn)){
    		renderResult(1,"参数PHONE不能为空");
    		return;
    	}else if(!ValidateKit.Mobile(msisdn)){
    		renderResult(2,"参数PHONE格式不正确");
    		return;
    	}else if(StrKit.isBlank(password)){
    		renderResult(3,"参数PASSWORD不能为空");
    		return;
    	}
    	//查询指定手机号用户
    	User user = userService.findByUsername(msisdn);
    	if(user==null||!CommonKit.passwordsMatch(password, user.getStr("password"))){
    		renderResult(4,"用户名或登录密码错误");
    		return;
    	}
    	//更新当前登录用户绑定的微信号
		WxUser wxUser = getCurrentWxUser();
		if(wxUser!=null){
			user.set("wxUserid", wxUser.get("id")).update();
		}
		//保存session以登录
		setSessionAttr(Constants.USER, user);
		renderSuccess();
    }
    
    /**
	 * 跳转至找回密码页面
	 */
	public void reset(){
		render("reset.jsp");
	}

	/**
	 * 找回密码时发送手机验证码
	 * @param PHONE 手机号码
	 */
	@Clear(AuthLoginInterceptor.class)
    public void sendResetPwdCode(){
    	String msisdn = getPara("phone");
    	if(StrKit.isBlank(msisdn)){
    		renderResult(1,"参数PHONE不能为空");
    		return;
    	}else if(userService.findByUsername(msisdn)==null){
    		renderResult(2,"手机号码未注册");
    		return;
    	}
    	//判断session中是否已经存在未过期的验证码
    	String randomNum = getSessionAttr("RESET_PWD_VALID_CODE");
		if(randomNum==null){
			//否则生成新的验证码
			randomNum = CommonKit.randomNum();
		}
		if(SMSKit.sendFindPwdCode(msisdn, randomNum)){
			setSessionAttr("RESET_PWD_VALID_CODE", randomNum);
			if(PropKit.getBoolean("debug.sms")){
				//短信接口调试模式时，将短信验证码返回给客户端
				renderSuccess(randomNum);
				return;
			}else{
				renderSuccess();
				return;
			}
		}
		renderFailed("验证码发送失败，请重新获取");
    }

	/**
	 * 重置密码
	 * @param PHONE 手机号码
	 * @param CODE 验证码
	 * @param PASSWORD 密码
	 * @param PASSWORDCONFIRM 确认密码
	 */
	@Clear(AuthLoginInterceptor.class)
	public void resetPwd(){
    	String msisdn = getPara("phone");
    	String code = getPara("code");
    	String password = getPara("password");
    	String passwordConfirm = getPara("passwordConfirm");
    	if(StrKit.isBlank(msisdn)){
    		renderResult(1,"参数PHONE不能为空");
    		return;
    	}else if(StrKit.isBlank(code)){
    		renderResult(2,"参数CODE不能为空");
    		return;
    	}else if(userService.findByUsername(msisdn)==null){
    		renderResult(3,"手机号未注册");
    		return;
    	}else if(StrKit.isBlank(password)){
    		renderResult(4,"密码为空");
    		return;
    	}else if(ValidateKit.Password_reg(password)){
    		renderResult(5,"密码只能填写数字、字母、下划线组合");
    		return;
    	}else if(password.length()<6||password.length()>18){
    		renderResult(6,"请保持密码长度在6-18之间");
    		return;
    	}else if(StrKit.isBlank(passwordConfirm)){
    		renderResult(7,"确认密码为空");
    		return;
    	}else if(!password.equals(passwordConfirm)){
    		renderResult(8,"两次密码输入不一致");
    		return;
    	}
    	//验证短信验证码
    	String codeInSession = getSessionAttr("RESET_PWD_VALID_CODE");
    	if(StrKit.isBlank(codeInSession)){
    		renderResult(10,"未获取短信验证码，请重新获取");
    		return;
    	}else if(!codeInSession.equals(code)){
    		renderResult(11,"验证码不正确");
    		return;
    	}
		//移除缓存中的验证码
    	removeSessionAttr("RESET_PWD_VALID_CODE");
		if(userService.updatePwdByUsername(CommonKit.encryptPassword(password), msisdn)){
			renderSuccess();
		}else{
			renderFailed("重置密码失败");
		}
	}
	
	/**
	 * 跳转意见反馈页面
	 */
	public void fbIndex() {
		render("my/feedback.jsp");
	}
	
	/**
     * 意见反馈
     * @param CONTEXT 反馈内容
     * @param CONTACT 联系电话或邮件
     */
    public void feedback(){
    	String context = getPara("CONTEXT");
    	String contact = getPara("CONTACT");
    	if(StrKit.isBlank(context)){
    		renderFailed("反馈内容不能为空");
    		return;
    	}else if(context.length()>500){
    		renderFailed("反馈内容太长了，请精简您的内容在500字以内");
    		return;
    	}
    	//如果当前有登录用户，则同时记录用户ID
    	User user = getCurrentUser();
    	if(userService.feedback(context, contact, (user!=null?user.getInt("id"):0))){
    		//返回
    		renderSuccess();
    		return;
    	}
		renderFailed("提交反馈失败");
    }
}
